#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>

void print_addr(const sockaddr_storage& addr) {
    if (addr.ss_family == AF_INET) {
        const sockaddr_in* addr4 = reinterpret_cast<const sockaddr_in*>(&addr);
        char ip_str[INET_ADDRSTRLEN];
        inet_ntop(AF_INET, &(addr4->sin_addr), ip_str, sizeof(ip_str));
        std::cout << "IP: " << ip_str << ", Port: " << ntohs(addr4->sin_port) << std::endl;
    }
}

int main() {
    int sockfd;
    struct sockaddr_storage server_addr, client_addr;
    socklen_t addr_len = sizeof(client_addr);
    char buffer[1024];

    // 创建 UDP socket
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0) {
        perror("Socket creation failed");
        return 1;
    }

    // 设置服务器地址 (绑定到 enp2s0 的 IP)
    struct ifreq ifr;
    memset(&ifr, 0, sizeof(ifr));
    strncpy(ifr.ifr_name, "enp2s0", IFNAMSIZ);
    if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
        perror("Failed to get enp2s0 address");
        close(sockfd);
        return 1;
    }

    struct sockaddr_in* server_addr_in = reinterpret_cast<struct sockaddr_in*>(&server_addr);
    server_addr_in->sin_family = AF_INET;
    server_addr_in->sin_port = htons(6015);  // 绑定 6015 端口
    server_addr_in->sin_addr = reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr;

    // 绑定 socket 到 enp2s0 的 IP 和 6015 端口
    if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0) {
        perror("Bind failed");
        close(sockfd);
        return 1;
    }

    std::cout << "Server bound to enp2s0, port 6015. Waiting for messages...\n";
    print_addr(server_addr);

    while (true) {
        // 接收客户端数据
        ssize_t recv_len = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0,
                                   (struct sockaddr*)&client_addr, &addr_len);
        if (recv_len < 0) {
            perror("Receive failed");
            continue;
        }
        buffer[recv_len] = '\0';  // 添加字符串结束符

        std::cout << "Received: " << buffer << " from ";
        print_addr(client_addr);

        // 检查是否收到 "hello"
        if (strcmp(buffer, "hello") == 0) {
            const char* reply = "echo-hello";
            ssize_t sent_len = sendto(sockfd, reply, strlen(reply), 0,
                                     (struct sockaddr*)&client_addr, addr_len);
            if (sent_len < 0) {
                perror("Send failed");
            } else {
                std::cout << "Sent: " << reply << " to client\n";
            }
        }
    }

    close(sockfd);
    return 0;
}